This is an R Markdown
Notebook. When you execute code within the notebook, the results appear
beneath the code.
Try executing this chunk by clicking the Run button within
the chunk or by placing your cursor inside it and pressing
Ctrl+Shift+Enter.
plot(cars)
Add a new chunk by clicking the Insert Chunk button on the
toolbar or by pressing Ctrl+Alt+I.
When you save the notebook, an HTML file containing the code and
output will be saved alongside it (click the Preview button or
press Ctrl+Shift+K to preview the HTML file).
The preview shows you a rendered HTML copy of the contents of the
editor. Consequently, unlike Knit, Preview does not
run any R code chunks. Instead, the output of the chunk when it was last
run in the editor is displayed.
# Load necessary libraries
library(ggplot2)
library(wordcloud)
library(RColorBrewer)
library(plotly)
library(grDevices)
library(dplyr)
library(grid)
# Load the dataset
data <- read.csv("C:\\Users\\khush\\Downloads\\Housing.csv")
# Check the first few rows of the dataset
head(data)
# Create a data frame for the word cloud
df <- data %>% count(furnishingstatus)
# Create the word cloud
wordcloud(words = df$furnishingstatus, freq = df$n,
colors = brewer.pal(8, "Dark2"),
scale = c(3, 0.5))
# Add a title
grid.text("Word Cloud of Furnishing Status",
x = unit(0.5, "npc"),
y = unit(1, "npc") - unit(1, "lines"),
gp = gpar(fontsize = 15, fontface = "bold"))

Word Cloud of Furnishing Status
Question Answered:
What is the distribution of different furnishing statuses in the
dataset?
Observation:
“Semi-furnished” is the most frequent furnishing status, followed
by “Unfurnished” and “Furnished.”
This indicates that a significant number of houses or apartments
in the dataset are semi-furnished, making it the dominant furnishing
status.
ggplot(data, aes(x = furnishingstatus, y = price, fill = furnishingstatus)) +
geom_boxplot() +
theme_minimal() +
labs(title = "Boxplot of Prices by Furnishing Status",
x = "Furnishing Status",
y = "Price") +
scale_fill_brewer(palette = "Set3") +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5) # Title styling
)

Boxplot of Prices by Furnishing Status
Question Answered:
How do prices vary based on the furnishing status?
Observation:
The median price is highest for “Furnished” properties, followed
by “Semi-furnished” and then “Unfurnished.”
Furnished properties tend to have the highest range of prices,
while unfurnished ones have a lower price range, showing a clear
relationship between furnishing and property value.
ggplot(data, aes(x = guestroom, y = area, fill = guestroom)) +
geom_boxplot() +
theme_minimal() +
labs(title = "Box Plot: Area vs. Guestroom",
x = "Guestroom",
y = "Area") +
scale_fill_brewer(palette = "Set3") +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5), # Title styling
axis.title.x = element_text(size = 12), # X-axis title styling
axis.title.y = element_text(size = 12) # Y-axis title styling
)

Boxplot of Area vs. Guestroom
Question Answered:
How does having a guestroom impact the area of the house?
Observation:
Houses with a guestroom tend to have a larger median area
compared to those without a guestroom.
This suggests that homes with guestrooms are typically larger,
providing more space overall.
ggplot(data, aes(x = factor(stories), y = area, fill = factor(stories))) +
geom_violin() +
labs(title = "Violin Plot of Area by Stories",
x = "Number of Stories",
y = "Area") +
theme_minimal() +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5), # Title styling
axis.title.x = element_text(size = 12), # X-axis title styling
axis.title.y = element_text(size = 12) # Y-axis title styling
)

Violin Plot of Area by Stories
Question Answered:
How does the area of a property vary based on the number of
stories?
Observations:
1-Story Buildings: These have the widest range
of areas, with a high density of smaller properties but also a few large
properties.
2-Story Buildings: The area distribution is more
concentrated compared to 1-story buildings, with most properties being
in the middle range of areas.
3-Story Buildings: The area distribution narrows
further, suggesting that properties with 3 stories tend to have a more
consistent area size. There are fewer extreme values, and the bulk of
the data lies in the middle.
4-Story Buildings:The distribution for 4-story
buildings is the narrowest, with most properties having similar
areas.
ggplot(data, aes(x = airconditioning, y = price, fill = airconditioning)) +
geom_violin(trim = FALSE, alpha = 0.6) +
theme_minimal() +
labs(title = "Violin Plot: Price vs. Air Conditioning",
x = "Air Conditioning",
y = "Price") +
scale_fill_manual(values = c("yes" = "lightblue", "no" = "lightcoral")) +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5), # Title styling
axis.title.x = element_text(size = 12), # X-axis title styling
axis.title.y = element_text(size = 12) # Y-axis title styling
)

Violin Plot: Price vs. Air Conditioning
Question Answered:
How does the price of a property vary based on the presence of air
conditioning?
Observations:
Properties without Air Conditioning: The price
distribution shows concentration of properties at lower prices.
Properties with Air Conditioning: The price
distribution here is also broad, but there seems to be a greater density
around mid- to higher-price ranges.
Properties with air conditioning generally have a higher price range,
which could suggest that air conditioning adds value or is a common
feature in more expensive properties.
ggplot(data, aes(x = area, y = price)) +
geom_point() +
geom_smooth(method = "lm", col = "blue") +
labs(title = "Linear Regression: Area vs Price",
x = "Area",
y = "Price") +
theme_minimal() +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5), # Title styling
axis.title.x = element_text(size = 12), # X-axis title styling
axis.title.y = element_text(size = 12) # Y-axis title styling
)
`geom_smooth()` using formula = 'y ~ x'

Linear Regression: Area vs Price
Question Answered:
How does the area of a property affect its price, and is there a
linear relationship between them?
Observations:
Positive Correlation: The scatter plot shows a
clear positive correlation between property area and price. As the area
increases, the price also tends to rise.
Linear Trend: The blue regression line indicates
the linear trend between area and price, suggesting that for larger
properties, the price generally increases at a consistent rate.
Variability: While there is a strong positive
correlation, the points are spread around the regression line,
particularly at higher areas. This indicates that while area is a strong
predictor of price, other factors may also influence property prices,
especially for larger properties.
ggplot(data, aes(x = area, y = price)) +
geom_point() +
geom_smooth(method = "loess", col = "red") +
labs(title = "Nonlinear Regression: Area vs Price",
x = "Area",
y = "Price") +
theme_minimal() +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5), # Title styling
axis.title.x = element_text(size = 12), # X-axis title styling
axis.title.y = element_text(size = 12) # Y-axis title styling
)
`geom_smooth()` using formula = 'y ~ x'

Nonlinear Regression: Area vs Price
Question Answered:
Is there a nonlinear relationship between the area of a property and
its price, and how does the price vary across different property
sizes?
Observations:
Nonlinear Trend: The red LOESS (Locally
Estimated Scatterplot Smoothing) curve shows a nonlinear relationship
between the area and price, suggesting that the relationship is not
purely linear. The price increase varies across different ranges of the
area.
Lower Areas: In the lower area range, the slope
of the curve is steeper, suggesting that as the area increases in this
range, the price rises more sharply.
Middle Areas: For medium-sized properties, the
price increases at a relatively steady pace.
Higher Areas: In the higher area range, the
curve starts to flatten, showing a diminishing rate of price increase.
This suggests that after a certain point, adding more area to a property
may result in only marginal increases in price, reflecting a saturation
point in value for very large properties.
plot_ly(data, x = ~area, y = ~bedrooms, z = ~price, type = 'scatter3d', mode = 'markers',
marker = list(size = 5, color = ~price, colorscale = 'Viridis')) %>%
layout(
title = '3D Plot: Area, Bedrooms, and Price',
scene = list(
xaxis = list(title = 'Area'),
yaxis = list(title = 'Bedrooms'),
zaxis = list(title = 'Price')
)
)
3D Plot: Area, Bedrooms, and Price:
Question Answered:
How do the number of bedrooms and the area of a property together
affect its price?
What is the 3-dimensional relationship between these three
variables?
Observations:
Price as the Color Gradient: The color gradient
(Viridis scale) represents price, with darker colors indicating lower
prices and brighter colors representing higher prices.
Positive Correlation: Generally, properties with
a higher number of bedrooms and larger areas tend to have higher prices,
visible through the clustering of brighter points in the upper-right
region of the plot.
Outliers: There may be some outliers where the
price is either unusually high for a smaller property or relatively low
for a larger one, potentially due to other factors not captured in this
3D plot (such as location, amenities, or condition of the
property).
ggplot(data, aes(x = factor(parking), y = price)) +
geom_jitter(aes(color = factor(parking))) +
labs(title = "Jitter Plot of Parking vs Price",
x = "Parking Spaces",
y = "Price") +
theme_minimal() +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5), # Title styling
axis.title.x = element_text(size = 12), # X-axis title styling
axis.title.y = element_text(size = 12) # Y-axis title styling
)

Jitter Plot of Parking vs. Price
Question Answered:
How does the number of parking spaces relate to property prices?
Observations:
Properties with more parking spaces (e.g., 2 or more) generally
tend to have higher prices, as observed by the concentration of points
at higher price ranges.
Most properties seem to have 1 or 2 parking spaces, and the
prices for these properties are more densely packed.
There are some outliers where properties with fewer parking
spaces have significantly higher prices, possibly due to other factors
like location or property size.
# Ensure bathrooms is treated as a factor
data$bathrooms <- as.factor(data$bathrooms)
ggplot(data, aes(x = bathrooms, y = price)) +
geom_jitter(width = 0.2, height = 0, aes(color = bathrooms)) +
labs(title = "Jitter Plot: Bathrooms vs. Price",
x = "Bathrooms",
y = "Price") +
theme_minimal() +
theme(
plot.title = element_text(size = 15, face = "bold", hjust = 0.5), # Title styling
axis.title.x = element_text(size = 12), # X-axis title styling
axis.title.y = element_text(size = 12) # Y-axis title styling
) +
scale_color_discrete(name = "Number of Bathrooms") # Use discrete color scale

Jitter Plot: Bathrooms vs. Price
Question Answered:
How does the number of bathrooms influence the price of a
property?
Observations:
Properties with more bathrooms (e.g., 2 or more) generally show a
trend toward higher prices. The concentration of higher-priced
properties increases as the number of bathrooms rises.
For properties with fewer bathrooms (1-2), there is a wider range
of prices, meaning that properties with the same number of bathrooms can
have very different prices depending on other factors.
This indicates that while the number of bathrooms influences
price, other features like area, location, and amenities also play a
significant role.
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLg0KDQpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouDQoNCmBgYHtyfQ0KcGxvdChjYXJzKQ0KYGBgDQoNCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4NCg0KV2hlbiB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2ssIGFuIEhUTUwgZmlsZSBjb250YWluaW5nIHRoZSBjb2RlIGFuZCBvdXRwdXQgd2lsbCBiZSBzYXZlZCBhbG9uZ3NpZGUgaXQgKGNsaWNrIHRoZSAqUHJldmlldyogYnV0dG9uIG9yIHByZXNzICpDdHJsK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuDQoNClRoZSBwcmV2aWV3IHNob3dzIHlvdSBhIHJlbmRlcmVkIEhUTUwgY29weSBvZiB0aGUgY29udGVudHMgb2YgdGhlIGVkaXRvci4gQ29uc2VxdWVudGx5LCB1bmxpa2UgKktuaXQqLCAqUHJldmlldyogZG9lcyBub3QgcnVuIGFueSBSIGNvZGUgY2h1bmtzLiBJbnN0ZWFkLCB0aGUgb3V0cHV0IG9mIHRoZSBjaHVuayB3aGVuIGl0IHdhcyBsYXN0IHJ1biBpbiB0aGUgZWRpdG9yIGlzIGRpc3BsYXllZC4NCg0KYGBge3J9DQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcw0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh3b3JkY2xvdWQpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShnckRldmljZXMpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShncmlkKQ0KYGBgDQoNCmBgYHtyfQ0KIyBMb2FkIHRoZSBkYXRhc2V0DQpkYXRhIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXGtodXNoXFxEb3dubG9hZHNcXEhvdXNpbmcuY3N2IikNCg0KIyBDaGVjayB0aGUgZmlyc3QgZmV3IHJvd3Mgb2YgdGhlIGRhdGFzZXQNCmhlYWQoZGF0YSkNCmBgYA0KDQpgYGB7cn0NCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSBmb3IgdGhlIHdvcmQgY2xvdWQNCmRmIDwtIGRhdGEgJT4lIGNvdW50KGZ1cm5pc2hpbmdzdGF0dXMpDQoNCiMgQ3JlYXRlIHRoZSB3b3JkIGNsb3VkDQp3b3JkY2xvdWQod29yZHMgPSBkZiRmdXJuaXNoaW5nc3RhdHVzLCBmcmVxID0gZGYkbiwgDQogICAgICAgICAgY29sb3JzID0gYnJld2VyLnBhbCg4LCAiRGFyazIiKSwNCiAgICAgICAgICBzY2FsZSA9IGMoMywgMC41KSkNCg0KZ3JpZC50ZXh0KCJXb3JkIENsb3VkIG9mIEZ1cm5pc2hpbmcgU3RhdHVzIiwgDQogICAgICAgICAgeCA9IHVuaXQoMC41LCAibnBjIiksIA0KICAgICAgICAgIHkgPSB1bml0KDEsICJucGMiKSAtIHVuaXQoMSwgImxpbmVzIiksIA0KICAgICAgICAgIGdwID0gZ3Bhcihmb250c2l6ZSA9IDE1LCBmb250ZmFjZSA9ICJib2xkIikpDQpgYGANCg0KIyMjICoqV29yZCBDbG91ZCBvZiBGdXJuaXNoaW5nIFN0YXR1cyoqDQoNCioqUXVlc3Rpb24gQW5zd2VyZWQqKjoNCg0KV2hhdCBpcyB0aGUgZGlzdHJpYnV0aW9uIG9mIGRpZmZlcmVudCBmdXJuaXNoaW5nIHN0YXR1c2VzIGluIHRoZSBkYXRhc2V0Pw0KDQoqKk9ic2VydmF0aW9uKio6DQoNCi0gICAiU2VtaS1mdXJuaXNoZWQiIGlzIHRoZSBtb3N0IGZyZXF1ZW50IGZ1cm5pc2hpbmcgc3RhdHVzLCBmb2xsb3dlZCBieSAiVW5mdXJuaXNoZWQiIGFuZCAiRnVybmlzaGVkLiINCg0KLSAgIFRoaXMgaW5kaWNhdGVzIHRoYXQgYSBzaWduaWZpY2FudCBudW1iZXIgb2YgaG91c2VzIG9yIGFwYXJ0bWVudHMgaW4gdGhlIGRhdGFzZXQgYXJlIHNlbWktZnVybmlzaGVkLCBtYWtpbmcgaXQgdGhlIGRvbWluYW50IGZ1cm5pc2hpbmcgc3RhdHVzLg0KDQpgYGB7cn0NCmdncGxvdChkYXRhLCBhZXMoeCA9IGZ1cm5pc2hpbmdzdGF0dXMsIHkgPSBwcmljZSwgZmlsbCA9IGZ1cm5pc2hpbmdzdGF0dXMpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh0aXRsZSA9ICJCb3hwbG90IG9mIFByaWNlcyBieSBGdXJuaXNoaW5nIFN0YXR1cyIsIA0KICAgICAgIHggPSAiRnVybmlzaGluZyBTdGF0dXMiLCANCiAgICAgICB5ID0gIlByaWNlIikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDMiKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSkgDQogICkNCmBgYA0KDQojIyMgKipCb3hwbG90IG9mIFByaWNlcyBieSBGdXJuaXNoaW5nIFN0YXR1cyoqDQoNCioqUXVlc3Rpb24gQW5zd2VyZWQqKjoNCg0KSG93IGRvIHByaWNlcyB2YXJ5IGJhc2VkIG9uIHRoZSBmdXJuaXNoaW5nIHN0YXR1cz8NCg0KKipPYnNlcnZhdGlvbioqOg0KDQotICAgVGhlIG1lZGlhbiBwcmljZSBpcyBoaWdoZXN0IGZvciAiRnVybmlzaGVkIiBwcm9wZXJ0aWVzLCBmb2xsb3dlZCBieSAiU2VtaS1mdXJuaXNoZWQiIGFuZCB0aGVuICJVbmZ1cm5pc2hlZC4iDQoNCi0gICBGdXJuaXNoZWQgcHJvcGVydGllcyB0ZW5kIHRvIGhhdmUgdGhlIGhpZ2hlc3QgcmFuZ2Ugb2YgcHJpY2VzLCB3aGlsZSB1bmZ1cm5pc2hlZCBvbmVzIGhhdmUgYSBsb3dlciBwcmljZSByYW5nZSwgc2hvd2luZyBhIGNsZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGZ1cm5pc2hpbmcgYW5kIHByb3BlcnR5IHZhbHVlLg0KDQpgYGB7cn0NCmdncGxvdChkYXRhLCBhZXMoeCA9IGd1ZXN0cm9vbSwgeSA9IGFyZWEsIGZpbGwgPSBndWVzdHJvb20pKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh0aXRsZSA9ICJCb3ggUGxvdDogQXJlYSB2cy4gR3Vlc3Ryb29tIiwgDQogICAgICAgeCA9ICJHdWVzdHJvb20iLCANCiAgICAgICB5ID0gIkFyZWEiKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MyIpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwgDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpICANCiAgKQ0KYGBgDQoNCiMjIyAqKkJveHBsb3Qgb2YgQXJlYSB2cy4gR3Vlc3Ryb29tKioNCg0KKipRdWVzdGlvbiBBbnN3ZXJlZCoqOg0KDQpIb3cgZG9lcyBoYXZpbmcgYSBndWVzdHJvb20gaW1wYWN0IHRoZSBhcmVhIG9mIHRoZSBob3VzZT8NCg0KKipPYnNlcnZhdGlvbioqOg0KDQotICAgSG91c2VzIHdpdGggYSBndWVzdHJvb20gdGVuZCB0byBoYXZlIGEgbGFyZ2VyIG1lZGlhbiBhcmVhIGNvbXBhcmVkIHRvIHRob3NlIHdpdGhvdXQgYSBndWVzdHJvb20uDQoNCi0gICBUaGlzIHN1Z2dlc3RzIHRoYXQgaG9tZXMgd2l0aCBndWVzdHJvb21zIGFyZSB0eXBpY2FsbHkgbGFyZ2VyLCBwcm92aWRpbmcgbW9yZSBzcGFjZSBvdmVyYWxsLg0KDQpgYGB7cn0NCmdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihzdG9yaWVzKSwgeSA9IGFyZWEsIGZpbGwgPSBmYWN0b3Ioc3RvcmllcykpKSArDQogIGdlb21fdmlvbGluKCkgKw0KICBsYWJzKHRpdGxlID0gIlZpb2xpbiBQbG90IG9mIEFyZWEgYnkgU3RvcmllcyIsIA0KICAgICAgIHggPSAiTnVtYmVyIG9mIFN0b3JpZXMiLCANCiAgICAgICB5ID0gIkFyZWEiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksIA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCANCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSAgIA0KICApDQpgYGANCg0KIyMjICoqVmlvbGluIFBsb3Qgb2YgQXJlYSBieSBTdG9yaWVzKioNCg0KKipRdWVzdGlvbiBBbnN3ZXJlZDoqKg0KDQpIb3cgZG9lcyB0aGUgYXJlYSBvZiBhIHByb3BlcnR5IHZhcnkgYmFzZWQgb24gdGhlIG51bWJlciBvZiBzdG9yaWVzPw0KDQoqKk9ic2VydmF0aW9uczoqKg0KDQotICAgKioxLVN0b3J5IEJ1aWxkaW5ncyoqOiBUaGVzZSBoYXZlIHRoZSB3aWRlc3QgcmFuZ2Ugb2YgYXJlYXMsIHdpdGggYSBoaWdoIGRlbnNpdHkgb2Ygc21hbGxlciBwcm9wZXJ0aWVzIGJ1dCBhbHNvIGEgZmV3IGxhcmdlIHByb3BlcnRpZXMuDQoNCi0gICAqKjItU3RvcnkgQnVpbGRpbmdzKio6IFRoZSBhcmVhIGRpc3RyaWJ1dGlvbiBpcyBtb3JlIGNvbmNlbnRyYXRlZCBjb21wYXJlZCB0byAxLXN0b3J5IGJ1aWxkaW5ncywgd2l0aCBtb3N0IHByb3BlcnRpZXMgYmVpbmcgaW4gdGhlIG1pZGRsZSByYW5nZSBvZiBhcmVhcy4NCg0KLSAgICoqMy1TdG9yeSBCdWlsZGluZ3MqKjogVGhlIGFyZWEgZGlzdHJpYnV0aW9uIG5hcnJvd3MgZnVydGhlciwgc3VnZ2VzdGluZyB0aGF0IHByb3BlcnRpZXMgd2l0aCAzIHN0b3JpZXMgdGVuZCB0byBoYXZlIGEgbW9yZSBjb25zaXN0ZW50IGFyZWEgc2l6ZS4gVGhlcmUgYXJlIGZld2VyIGV4dHJlbWUgdmFsdWVzLCBhbmQgdGhlIGJ1bGsgb2YgdGhlIGRhdGEgbGllcyBpbiB0aGUgbWlkZGxlLg0KDQotICAgKio0LVN0b3J5IEJ1aWxkaW5ncyoqOlRoZSBkaXN0cmlidXRpb24gZm9yIDQtc3RvcnkgYnVpbGRpbmdzIGlzIHRoZSBuYXJyb3dlc3QsIHdpdGggbW9zdCBwcm9wZXJ0aWVzIGhhdmluZyBzaW1pbGFyIGFyZWFzLg0KDQpgYGB7cn0NCmdncGxvdChkYXRhLCBhZXMoeCA9IGFpcmNvbmRpdGlvbmluZywgeSA9IHByaWNlLCBmaWxsID0gYWlyY29uZGl0aW9uaW5nKSkgKw0KICBnZW9tX3Zpb2xpbih0cmltID0gRkFMU0UsIGFscGhhID0gMC42KSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIGxhYnModGl0bGUgPSAiVmlvbGluIFBsb3Q6IFByaWNlIHZzLiBBaXIgQ29uZGl0aW9uaW5nIiwgDQogICAgICAgeCA9ICJBaXIgQ29uZGl0aW9uaW5nIiwgDQogICAgICAgeSA9ICJQcmljZSIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygieWVzIiA9ICJsaWdodGJsdWUiLCAibm8iID0gImxpZ2h0Y29yYWwiKSkgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAwLjUpLCANCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgIA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpICAgDQogICkNCmBgYA0KDQojIyMgVmlvbGluIFBsb3Q6IFByaWNlIHZzLiBBaXIgQ29uZGl0aW9uaW5nDQoNCioqUXVlc3Rpb24gQW5zd2VyZWQ6KioNCg0KSG93IGRvZXMgdGhlIHByaWNlIG9mIGEgcHJvcGVydHkgdmFyeSBiYXNlZCBvbiB0aGUgcHJlc2VuY2Ugb2YgYWlyIGNvbmRpdGlvbmluZz8NCg0KKipPYnNlcnZhdGlvbnM6KioNCg0KLSAgICoqUHJvcGVydGllcyB3aXRob3V0IEFpciBDb25kaXRpb25pbmcqKjogVGhlIHByaWNlIGRpc3RyaWJ1dGlvbiBzaG93cyBjb25jZW50cmF0aW9uIG9mIHByb3BlcnRpZXMgYXQgbG93ZXIgcHJpY2VzLg0KDQotICAgKipQcm9wZXJ0aWVzIHdpdGggQWlyIENvbmRpdGlvbmluZyoqOiBUaGUgcHJpY2UgZGlzdHJpYnV0aW9uIGhlcmUgaXMgYWxzbyBicm9hZCwgYnV0IHRoZXJlIHNlZW1zIHRvIGJlIGEgZ3JlYXRlciBkZW5zaXR5IGFyb3VuZCBtaWQtIHRvIGhpZ2hlci1wcmljZSByYW5nZXMuDQoNCiAgICBQcm9wZXJ0aWVzIHdpdGggYWlyIGNvbmRpdGlvbmluZyBnZW5lcmFsbHkgaGF2ZSBhIGhpZ2hlciBwcmljZSByYW5nZSwgd2hpY2ggY291bGQgc3VnZ2VzdCB0aGF0IGFpciBjb25kaXRpb25pbmcgYWRkcyB2YWx1ZSBvciBpcyBhIGNvbW1vbiBmZWF0dXJlIGluIG1vcmUgZXhwZW5zaXZlIHByb3BlcnRpZXMuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEsIGFlcyh4ID0gYXJlYSwgeSA9IHByaWNlKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2wgPSAiYmx1ZSIpICsNCiAgbGFicyh0aXRsZSA9ICJMaW5lYXIgUmVncmVzc2lvbjogQXJlYSB2cyBQcmljZSIsIA0KICAgICAgIHggPSAiQXJlYSIsIA0KICAgICAgIHkgPSAiUHJpY2UiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksICANCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikgICANCiAgKQ0KYGBgDQoNCiMjIyAqKkxpbmVhciBSZWdyZXNzaW9uOiBBcmVhIHZzIFByaWNlKioNCg0KKipRdWVzdGlvbiBBbnN3ZXJlZDoqKg0KDQpIb3cgZG9lcyB0aGUgYXJlYSBvZiBhIHByb3BlcnR5IGFmZmVjdCBpdHMgcHJpY2UsIGFuZCBpcyB0aGVyZSBhIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGVtPw0KDQoqKk9ic2VydmF0aW9uczoqKg0KDQotICAgKipQb3NpdGl2ZSBDb3JyZWxhdGlvbioqOiBUaGUgc2NhdHRlciBwbG90IHNob3dzIGEgY2xlYXIgcG9zaXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBwcm9wZXJ0eSBhcmVhIGFuZCBwcmljZS4gQXMgdGhlIGFyZWEgaW5jcmVhc2VzLCB0aGUgcHJpY2UgYWxzbyB0ZW5kcyB0byByaXNlLg0KDQotICAgKipMaW5lYXIgVHJlbmQqKjogVGhlIGJsdWUgcmVncmVzc2lvbiBsaW5lIGluZGljYXRlcyB0aGUgbGluZWFyIHRyZW5kIGJldHdlZW4gYXJlYSBhbmQgcHJpY2UsIHN1Z2dlc3RpbmcgdGhhdCBmb3IgbGFyZ2VyIHByb3BlcnRpZXMsIHRoZSBwcmljZSBnZW5lcmFsbHkgaW5jcmVhc2VzIGF0IGEgY29uc2lzdGVudCByYXRlLg0KDQotICAgKipWYXJpYWJpbGl0eSoqOiBXaGlsZSB0aGVyZSBpcyBhIHN0cm9uZyBwb3NpdGl2ZSBjb3JyZWxhdGlvbiwgdGhlIHBvaW50cyBhcmUgc3ByZWFkIGFyb3VuZCB0aGUgcmVncmVzc2lvbiBsaW5lLCBwYXJ0aWN1bGFybHkgYXQgaGlnaGVyIGFyZWFzLiBUaGlzIGluZGljYXRlcyB0aGF0IHdoaWxlIGFyZWEgaXMgYSBzdHJvbmcgcHJlZGljdG9yIG9mIHByaWNlLCBvdGhlciBmYWN0b3JzIG1heSBhbHNvIGluZmx1ZW5jZSBwcm9wZXJ0eSBwcmljZXMsIGVzcGVjaWFsbHkgZm9yIGxhcmdlciBwcm9wZXJ0aWVzLg0KDQpgYGB7cn0NCmdncGxvdChkYXRhLCBhZXMoeCA9IGFyZWEsIHkgPSBwcmljZSkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgY29sID0gInJlZCIpICsNCiAgbGFicyh0aXRsZSA9ICJOb25saW5lYXIgUmVncmVzc2lvbjogQXJlYSB2cyBQcmljZSIsIA0KICAgICAgIHggPSAiQXJlYSIsIA0KICAgICAgIHkgPSAiUHJpY2UiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksICANCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSAgIA0KICApDQpgYGANCg0KIyMjIE5vbmxpbmVhciBSZWdyZXNzaW9uOiBBcmVhIHZzIFByaWNlDQoNCioqUXVlc3Rpb24gQW5zd2VyZWQ6KioNCg0KSXMgdGhlcmUgYSBub25saW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGFyZWEgb2YgYSBwcm9wZXJ0eSBhbmQgaXRzIHByaWNlLCBhbmQgaG93IGRvZXMgdGhlIHByaWNlIHZhcnkgYWNyb3NzIGRpZmZlcmVudCBwcm9wZXJ0eSBzaXplcz8NCg0KKipPYnNlcnZhdGlvbnM6KioNCg0KLSAgICoqTm9ubGluZWFyIFRyZW5kKio6IFRoZSByZWQgTE9FU1MgKExvY2FsbHkgRXN0aW1hdGVkIFNjYXR0ZXJwbG90IFNtb290aGluZykgY3VydmUgc2hvd3MgYSBub25saW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGFyZWEgYW5kIHByaWNlLCBzdWdnZXN0aW5nIHRoYXQgdGhlIHJlbGF0aW9uc2hpcCBpcyBub3QgcHVyZWx5IGxpbmVhci4gVGhlIHByaWNlIGluY3JlYXNlIHZhcmllcyBhY3Jvc3MgZGlmZmVyZW50IHJhbmdlcyBvZiB0aGUgYXJlYS4NCg0KLSAgICoqTG93ZXIgQXJlYXMqKjogSW4gdGhlIGxvd2VyIGFyZWEgcmFuZ2UsIHRoZSBzbG9wZSBvZiB0aGUgY3VydmUgaXMgc3RlZXBlciwgc3VnZ2VzdGluZyB0aGF0IGFzIHRoZSBhcmVhIGluY3JlYXNlcyBpbiB0aGlzIHJhbmdlLCB0aGUgcHJpY2UgcmlzZXMgbW9yZSBzaGFycGx5Lg0KDQotICAgKipNaWRkbGUgQXJlYXMqKjogRm9yIG1lZGl1bS1zaXplZCBwcm9wZXJ0aWVzLCB0aGUgcHJpY2UgaW5jcmVhc2VzIGF0IGEgcmVsYXRpdmVseSBzdGVhZHkgcGFjZS4NCg0KLSAgICoqSGlnaGVyIEFyZWFzKio6IEluIHRoZSBoaWdoZXIgYXJlYSByYW5nZSwgdGhlIGN1cnZlIHN0YXJ0cyB0byBmbGF0dGVuLCBzaG93aW5nIGEgZGltaW5pc2hpbmcgcmF0ZSBvZiBwcmljZSBpbmNyZWFzZS4gVGhpcyBzdWdnZXN0cyB0aGF0IGFmdGVyIGEgY2VydGFpbiBwb2ludCwgYWRkaW5nIG1vcmUgYXJlYSB0byBhIHByb3BlcnR5IG1heSByZXN1bHQgaW4gb25seSBtYXJnaW5hbCBpbmNyZWFzZXMgaW4gcHJpY2UsIHJlZmxlY3RpbmcgYSBzYXR1cmF0aW9uIHBvaW50IGluIHZhbHVlIGZvciB2ZXJ5IGxhcmdlIHByb3BlcnRpZXMuDQoNCmBgYHtyfQ0KcGxvdF9seShkYXRhLCB4ID0gfmFyZWEsIHkgPSB+YmVkcm9vbXMsIHogPSB+cHJpY2UsIHR5cGUgPSAnc2NhdHRlcjNkJywgbW9kZSA9ICdtYXJrZXJzJywNCiAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gNSwgY29sb3IgPSB+cHJpY2UsIGNvbG9yc2NhbGUgPSAnVmlyaWRpcycpKSAlPiUNCiAgbGF5b3V0KA0KICAgIHRpdGxlID0gJzNEIFBsb3Q6IEFyZWEsIEJlZHJvb21zLCBhbmQgUHJpY2UnLA0KICAgIHNjZW5lID0gbGlzdCgNCiAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICdBcmVhJyksDQogICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnQmVkcm9vbXMnKSwNCiAgICAgIHpheGlzID0gbGlzdCh0aXRsZSA9ICdQcmljZScpDQogICAgKQ0KICApDQpgYGANCg0KIyMjICoqM0QgUGxvdDogQXJlYSwgQmVkcm9vbXMsIGFuZCBQcmljZSoqOg0KDQoqKlF1ZXN0aW9uIEFuc3dlcmVkOioqDQoNCkhvdyBkbyB0aGUgbnVtYmVyIG9mIGJlZHJvb21zIGFuZCB0aGUgYXJlYSBvZiBhIHByb3BlcnR5IHRvZ2V0aGVyIGFmZmVjdCBpdHMgcHJpY2U/DQoNCldoYXQgaXMgdGhlIDMtZGltZW5zaW9uYWwgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlc2UgdGhyZWUgdmFyaWFibGVzPw0KDQoqKk9ic2VydmF0aW9uczoqKg0KDQotICAgKipQcmljZSBhcyB0aGUgQ29sb3IgR3JhZGllbnQqKjogVGhlIGNvbG9yIGdyYWRpZW50IChWaXJpZGlzIHNjYWxlKSByZXByZXNlbnRzIHByaWNlLCB3aXRoIGRhcmtlciBjb2xvcnMgaW5kaWNhdGluZyBsb3dlciBwcmljZXMgYW5kIGJyaWdodGVyIGNvbG9ycyByZXByZXNlbnRpbmcgaGlnaGVyIHByaWNlcy4NCg0KLSAgICoqUG9zaXRpdmUgQ29ycmVsYXRpb24qKjogR2VuZXJhbGx5LCBwcm9wZXJ0aWVzIHdpdGggYSBoaWdoZXIgbnVtYmVyIG9mIGJlZHJvb21zIGFuZCBsYXJnZXIgYXJlYXMgdGVuZCB0byBoYXZlIGhpZ2hlciBwcmljZXMsIHZpc2libGUgdGhyb3VnaCB0aGUgY2x1c3RlcmluZyBvZiBicmlnaHRlciBwb2ludHMgaW4gdGhlIHVwcGVyLXJpZ2h0IHJlZ2lvbiBvZiB0aGUgcGxvdC4NCg0KLSAgICoqT3V0bGllcnMqKjogVGhlcmUgbWF5IGJlIHNvbWUgb3V0bGllcnMgd2hlcmUgdGhlIHByaWNlIGlzIGVpdGhlciB1bnVzdWFsbHkgaGlnaCBmb3IgYSBzbWFsbGVyIHByb3BlcnR5IG9yIHJlbGF0aXZlbHkgbG93IGZvciBhIGxhcmdlciBvbmUsIHBvdGVudGlhbGx5IGR1ZSB0byBvdGhlciBmYWN0b3JzIG5vdCBjYXB0dXJlZCBpbiB0aGlzIDNEIHBsb3QgKHN1Y2ggYXMgbG9jYXRpb24sIGFtZW5pdGllcywgb3IgY29uZGl0aW9uIG9mIHRoZSBwcm9wZXJ0eSkuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEsIGFlcyh4ID0gZmFjdG9yKHBhcmtpbmcpLCB5ID0gcHJpY2UpKSArDQogIGdlb21faml0dGVyKGFlcyhjb2xvciA9IGZhY3RvcihwYXJraW5nKSkpICsNCiAgbGFicyh0aXRsZSA9ICJKaXR0ZXIgUGxvdCBvZiBQYXJraW5nIHZzIFByaWNlIiwgDQogICAgICAgeCA9ICJQYXJraW5nIFNwYWNlcyIsIA0KICAgICAgIHkgPSAiUHJpY2UiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksICANCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgIA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpICAgDQogICkNCmBgYA0KDQojIyMgKipKaXR0ZXIgUGxvdCBvZiBQYXJraW5nIHZzLiBQcmljZSoqDQoNCioqUXVlc3Rpb24gQW5zd2VyZWQ6KioNCg0KSG93IGRvZXMgdGhlIG51bWJlciBvZiBwYXJraW5nIHNwYWNlcyByZWxhdGUgdG8gcHJvcGVydHkgcHJpY2VzPw0KDQoqKk9ic2VydmF0aW9uczoqKg0KDQotICAgUHJvcGVydGllcyB3aXRoIG1vcmUgcGFya2luZyBzcGFjZXMgKGUuZy4sIDIgb3IgbW9yZSkgZ2VuZXJhbGx5IHRlbmQgdG8gaGF2ZSBoaWdoZXIgcHJpY2VzLCBhcyBvYnNlcnZlZCBieSB0aGUgY29uY2VudHJhdGlvbiBvZiBwb2ludHMgYXQgaGlnaGVyIHByaWNlIHJhbmdlcy4NCg0KLSAgIE1vc3QgcHJvcGVydGllcyBzZWVtIHRvIGhhdmUgMSBvciAyIHBhcmtpbmcgc3BhY2VzLCBhbmQgdGhlIHByaWNlcyBmb3IgdGhlc2UgcHJvcGVydGllcyBhcmUgbW9yZSBkZW5zZWx5IHBhY2tlZC4NCg0KLSAgIFRoZXJlIGFyZSBzb21lIG91dGxpZXJzIHdoZXJlIHByb3BlcnRpZXMgd2l0aCBmZXdlciBwYXJraW5nIHNwYWNlcyBoYXZlIHNpZ25pZmljYW50bHkgaGlnaGVyIHByaWNlcywgcG9zc2libHkgZHVlIHRvIG90aGVyIGZhY3RvcnMgbGlrZSBsb2NhdGlvbiBvciBwcm9wZXJ0eSBzaXplLg0KDQpgYGB7cn0NCmRhdGEkYmF0aHJvb21zIDwtIGFzLmZhY3RvcihkYXRhJGJhdGhyb29tcykNCg0KZ2dwbG90KGRhdGEsIGFlcyh4ID0gYmF0aHJvb21zLCB5ID0gcHJpY2UpKSArDQogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBoZWlnaHQgPSAwLCBhZXMoY29sb3IgPSBiYXRocm9vbXMpKSArDQogIGxhYnModGl0bGUgPSAiSml0dGVyIFBsb3Q6IEJhdGhyb29tcyB2cy4gUHJpY2UiLCANCiAgICAgICB4ID0gIkJhdGhyb29tcyIsIA0KICAgICAgIHkgPSAiUHJpY2UiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksICANCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikgIA0KICApICsNCiAgc2NhbGVfY29sb3JfZGlzY3JldGUobmFtZSA9ICJOdW1iZXIgb2YgQmF0aHJvb21zIikgIA0KYGBgDQoNCiMjIyAqKkppdHRlciBQbG90OiBCYXRocm9vbXMgdnMuIFByaWNlKioNCg0KKipRdWVzdGlvbiBBbnN3ZXJlZDoqKg0KDQpIb3cgZG9lcyB0aGUgbnVtYmVyIG9mIGJhdGhyb29tcyBpbmZsdWVuY2UgdGhlIHByaWNlIG9mIGEgcHJvcGVydHk/DQoNCioqT2JzZXJ2YXRpb25zOioqDQoNCi0gICAgUHJvcGVydGllcyB3aXRoIG1vcmUgYmF0aHJvb21zIChlLmcuLCAyIG9yIG1vcmUpIGdlbmVyYWxseSBzaG93IGEgdHJlbmQgdG93YXJkIGhpZ2hlciBwcmljZXMuIFRoZSBjb25jZW50cmF0aW9uIG9mIGhpZ2hlci1wcmljZWQgcHJvcGVydGllcyBpbmNyZWFzZXMgYXMgdGhlIG51bWJlciBvZiBiYXRocm9vbXMgcmlzZXMuDQoNCi0gICAgRm9yIHByb3BlcnRpZXMgd2l0aCBmZXdlciBiYXRocm9vbXMgKDEtMiksIHRoZXJlIGlzIGEgd2lkZXIgcmFuZ2Ugb2YgcHJpY2VzLCBtZWFuaW5nIHRoYXQgcHJvcGVydGllcyB3aXRoIHRoZSBzYW1lIG51bWJlciBvZiBiYXRocm9vbXMgY2FuIGhhdmUgdmVyeSBkaWZmZXJlbnQgcHJpY2VzIGRlcGVuZGluZyBvbiBvdGhlciBmYWN0b3JzLg0KDQotICAgVGhpcyBpbmRpY2F0ZXMgdGhhdCB3aGlsZSB0aGUgbnVtYmVyIG9mIGJhdGhyb29tcyBpbmZsdWVuY2VzIHByaWNlLCBvdGhlciBmZWF0dXJlcyBsaWtlIGFyZWEsIGxvY2F0aW9uLCBhbmQgYW1lbml0aWVzIGFsc28gcGxheSBhIHNpZ25pZmljYW50IHJvbGUuDQo=